﻿using Newtonsoft.Json;
using System.ComponentModel;

namespace Region.Spider.aoshang
{
    public static class AoshangTools
    {
        public const int MaxCodeLength = 6;
        public const int MaxDep = 3;

        public const string AreaFileName = "aoshang/area.json";
        public const string SourceAreaFileName = "aoshang/source_areas.json";

        public const string ExtraAreasFileName = "aoshang/area_extra.json";
        public const string SourceExtraAreasFileName = "aoshang/source_area_extra.json";

        public const string OtherAreaFileName = "aoshang/other_areas.json";
        public const string SourceOtherAreaFileName = "aoshang/source_other_areas.json";


        public static string OtherAreasFilePath => File.Exists(OtherAreaFileName)
                ? OtherAreaFileName
                : SourceOtherAreaFileName;
        public static string AreasFilePath => File.Exists(AreaFileName)
                ? AreaFileName
                : SourceAreaFileName;
        public static string ExtraAreasFilePath => File.Exists(ExtraAreasFileName)
                ? ExtraAreasFileName
                : SourceExtraAreasFileName;

        public static string FormatCode(string code)
        {
            //if (code.Length > MaxCodeLength)
            //    code = code.Substring(0, MaxCodeLength);
            if(code.Length>=MaxCodeLength)
                return code;
            return code.PadRight(MaxCodeLength, '0');
        }

        public static List<AoshangAreaItem> ToAoshangItems(IEnumerable<AreaItem> items, int currDep = 1)
        {
            if (currDep > MaxDep)
                return null;
            currDep++;
            var asItems = new List<AoshangAreaItem>();
            foreach (var item in items)
            {
                var asItem = new AoshangAreaItem();
                asItem.code = FormatCode(item.Code);
                asItem.name = item.Name;
                if (item.Children != null)
                    asItem.area = ToAoshangItems(item.Children, currDep);
                asItems.Add(asItem);
            }
            return asItems;
        }


        public static async Task GenerateJsonFileAsync(IEnumerable<AreaItem> items)
        {
            //生成新文件
            var otherItems = await Tools.ReadToJsonAsync<AoshangAreaItem[]>(OtherAreasFilePath);
            var newItems = ToAoshangItems(items)
                .Union(otherItems);

            //处理历史数据中被删除的部分
            var currItems = await Tools.ReadToJsonAsync<AoshangAreaItem[]>(AreasFilePath);
            var currExtraItems = await Tools.ReadToJsonAsync<List<AoshangAreaItem>>(ExtraAreasFilePath);
            var extraItems = GetExtraItems(currExtraItems, currItems, newItems);

            //生成文件
            await Tools.GenerateJsonFileAsync(newItems, AreaFileName);
            await Tools.GenerateJsonFileAsync(extraItems, ExtraAreasFileName);

            //File.Copy(filePath, AreaFileName, true);
            //File.Copy(extraFilePath, ExtraAreasFileName, true);
        }

        /// <summary>
        /// 获取在历史json中有新json没有的数据
        /// </summary>
        public static List<AoshangAreaItem> GetExtraItems(
            List<AoshangAreaItem> currExtraItems,
            IEnumerable<AoshangAreaItem> currItems,
            IEnumerable<AoshangAreaItem> newItems)
        {
            //添加逻辑
            //如果在New中不存在则且不当前ext中不存在，直接添加 
            //如果在new中存在，则处理子级
            var extItems = currExtraItems ?? new List<AoshangAreaItem>();
            foreach (var item in currItems)
            {
                var newItem = newItems.FirstOrDefault(t => t.code == item.code);
                var extItem = extItems.FirstOrDefault(t => t.code == item.code);
                //新数据已去掉，当前扩展中没有，添加
                if (newItem == null)
                {
                    if (extItem == null)
                        extItems.Add(item);
                    continue;
                }
                //新数据有，但是子级变化
                if (item.area != null)
                {
                    item.area = GetExtraItems(extItem?.area, item.area, newItem.area);
                    if (item.area?.Any() == true)
                    {
                        if (extItem == null)
                            extItems.Add(item);
                        else
                        {
                            extItem.area = item.area;
                        }
                    }
                }

            }
            return extItems;
        }
    }
}
